package la.renzhen.rtpt.admin.source.consul;

import com.alibaba.fastjson.JSON;
import com.ecwid.consul.v1.ConsistencyMode;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.kv.model.GetValue;
import la.renzhen.rtpt.admin.source.CenterConfigurationSource;
import la.renzhen.rtpt.admin.source.ConfigElement;
import la.renzhen.rtpt.admin.util.Strings;
import lombok.NonNull;
import org.springframework.util.StringUtils;

import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * @author <a href="mailto:zhouhaichao@2008.sina.com">haiker</a>
 * @version 11/05/2018 4:50 PM
 */
public class ConsulCenterConfigurationSource implements CenterConfigurationSource {

    ConsulClient consulClient;
    String module;

    public ConsulCenterConfigurationSource(ConsulClient consulClient, String module) {
        this.consulClient = consulClient;
        this.module = module;
    }

    @Override
    public List<String> environments() {
        String keyPrefix = module + "/";
        QueryParams queryParams = QueryParams.Builder.builder().setConsistencyMode(ConsistencyMode.CONSISTENT).build();
        Response<List<String>> response = consulClient.getKVKeysOnly(keyPrefix, "/", null, queryParams);
        if (response.getValue() == null) {
            return Collections.emptyList();
        }
        return response.getValue().stream().map(s -> Strings.sub(s, keyPrefix.length(), -1)).collect(Collectors.toList());
    }

    @Override
    public List<ConfigElement> loadAll(@NonNull String environment, @NonNull String prefix) {
        Response<List<GetValue>> response = consulClient.getKVValues(key(environment, prefix));
        if (response.getValue() == null) {
            return Collections.emptyList();
        }
        return response.getValue()
                .stream()
                .map(s -> JSON.parseObject(s.getDecodedValue(Charset.forName("UTF-8")), ConfigElement.class))
                .collect(Collectors.toList());
    }

    @Override
    public ConfigElement get(@NonNull String environment, @NonNull String key) {
        Response<GetValue> response = consulClient.getKVValue(key(environment, key));
        if (response.getValue() == null) {
            return null;
        }
        String content = response.getValue().getDecodedValue(Charset.forName("UTF-8"));
        return JSON.parseObject(content, ConfigElement.class);
    }

    @Override
    public void set(@NonNull ConfigElement item) {
        consulClient.setKVValue(key(item.getEnvironment(), item.getKey()), JSON.toJSONString(item));
    }

    @Override
    public void del(@NonNull String environment, @NonNull String key) {
        consulClient.deleteKVValue(key(environment, key));
    }


    protected String key(@NonNull String environment, @NonNull String key) {
        StringBuilder keys = new StringBuilder(module);
        keys.append("/");
        keys.append(environment).append("/");
        if (StringUtils.hasText(key)) {
            keys.append(key);
        }
        return keys.toString();
    }
}
